home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / iritsm3s.zip / SBSPEVAL.C < prev    next >
C/C++ Source or Header  |  1991-05-18  |  5KB  |  161 lines

  1. /******************************************************************************
  2. * SBspEval.c - Bspline surfaces handling routines - evaluation routines.      *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Mar. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include <string.h>
  8. #include "cagd_loc.h"
  9.  
  10. /******************************************************************************
  11. * Evaluate the given tensor product Bspline surface at a given point, by      *
  12. * extracting an isoparamteric curve along u and evaluating v in it.          *
  13. *                                          *
  14. *        u -->                                  *
  15. *     +----------------------+                              *
  16. *     |P0         Pi-1|                              *
  17. *   V |Pi        P2i-1|    Parametric space orientation - control mesh.  *
  18. *    ||                 |                              *
  19. *    v|Pn-i         Pn-1|                              *
  20. *     +----------------------+                              *
  21. *                                          *
  22. ******************************************************************************/
  23. CagdRType *BspSrfEvalAtParam(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  24. {
  25.     CagdRType *Pt;
  26.     CagdCrvStruct
  27.     *IsoCrv = BspSrfCrvFromSrf(Srf, u, CAGD_CONST_U_DIR);
  28.  
  29.     if (!BspKnotParamInDomain(IsoCrv -> KnotVector, IsoCrv -> Length,
  30.                             IsoCrv -> Order, v))
  31.     FATAL_ERROR(CAGD_ERR_V_NOT_IN_SRF);
  32.  
  33.     Pt = BspCrvEvalAtParam(IsoCrv, v);
  34.  
  35.     CagdCrvFree(IsoCrv);
  36.  
  37.     return Pt;
  38. }
  39.  
  40. /******************************************************************************
  41. * Extract an isoline curve out of the given tensor product Bspline surface.   *
  42. * Operations should prefer the CONST_U_DIR, in which the extraction is          *
  43. * somewhat faster if it is possible.                          *
  44. ******************************************************************************/
  45. CagdCrvStruct *BspSrfCrvFromSrf(CagdSrfStruct *Srf, CagdRType t,
  46.                             CagdSrfDirType dir)
  47. {
  48.     CagdCrvStruct *Crv;
  49.     CagdBType
  50.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  51.     int i, j, CrvLen,
  52.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  53.     CagdRType *CrvP, *SrfP;
  54.  
  55.     switch (dir) {
  56.     case CAGD_CONST_U_DIR:
  57.         if (!BspKnotParamInDomain(Srf -> UKnotVector, Srf -> ULength,
  58.                               Srf -> UOrder, t))
  59.         FATAL_ERROR(CAGD_ERR_U_NOT_IN_SRF);
  60.         Crv = BspCrvNew(CrvLen = Srf -> VLength,
  61.                 Srf -> VOrder, Srf -> PType);
  62.         GEN_COPY(Crv -> KnotVector, Srf -> VKnotVector,
  63.             sizeof(CagdRType) * (Srf -> VLength + Srf -> VOrder));
  64.  
  65.         for (i = IsNotRational; i <= MaxCoord; i++) {
  66.         CrvP = Crv -> Points[i];
  67.         SrfP = Srf -> Points[i];
  68.         for (j = 0; j < CrvLen; j++) {
  69.             *CrvP++ = BspCrvEvalVecAtParam(SrfP, CAGD_NEXT_U(Srf),
  70.                        Srf -> UKnotVector, Srf -> UOrder,
  71.                        Srf -> ULength, t);
  72.             SrfP += CAGD_NEXT_V(Srf);
  73.         }
  74.         }
  75.         break;
  76.     case CAGD_CONST_V_DIR:
  77.         if (!BspKnotParamInDomain(Srf -> VKnotVector, Srf -> VLength,
  78.                               Srf -> VOrder, t))
  79.         FATAL_ERROR(CAGD_ERR_V_NOT_IN_SRF);
  80.         Crv = BspCrvNew(CrvLen = Srf -> ULength,
  81.                 Srf -> UOrder, Srf -> PType);
  82.         GEN_COPY(Crv -> KnotVector, Srf -> UKnotVector,
  83.             sizeof(CagdRType) * (Srf -> ULength + Srf -> UOrder));
  84.  
  85.         for (i = IsNotRational; i <= MaxCoord; i++) {
  86.         CrvP = Crv -> Points[i];
  87.         SrfP = Srf -> Points[i];
  88.         for (j = 0; j < CrvLen; j++) {
  89.             *CrvP++ = BspCrvEvalVecAtParam(SrfP, CAGD_NEXT_V(Srf),
  90.                        Srf -> VKnotVector, Srf -> VOrder,
  91.                        Srf -> VLength, t);
  92.             SrfP += CAGD_NEXT_U(Srf);
  93.         }
  94.         }
  95.         break;
  96.     default:
  97.         FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
  98.         break;
  99.     }
  100.     return Crv;
  101. }
  102.  
  103. /******************************************************************************
  104. * Extract an isoline curve out of the given mesh row/col.              *
  105. * The provided (zero based) Index specifies which row/col Index to extract.   *
  106. ******************************************************************************/
  107. CagdCrvStruct *BspSrfCrvFromMesh(CagdSrfStruct *Srf, int Index,
  108.                             CagdSrfDirType Dir)
  109. {
  110.     CagdCrvStruct *Crv;
  111.     CagdBType
  112.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  113.     int i, j, CrvLen,
  114.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  115.     CagdRType *CrvP, *SrfP;
  116.  
  117.     switch (Dir) {
  118.     case CAGD_CONST_U_DIR:
  119.         if (Index + 1 > Srf -> ULength)
  120.         FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  121.  
  122.         Crv = BspCrvNew(CrvLen = Srf -> VLength,
  123.                 Srf -> VOrder, Srf -> PType);
  124.         GEN_COPY(Crv -> KnotVector, Srf -> VKnotVector,
  125.             sizeof(CagdRType) * (Srf -> VLength + Srf -> VOrder));
  126.  
  127.         for (i = IsNotRational; i <= MaxCoord; i++) {
  128.         CrvP = Crv -> Points[i];
  129.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_U(Srf);
  130.         for (j = 0; j < CrvLen; j++) {
  131.             *CrvP++ = *SrfP;
  132.             SrfP += CAGD_NEXT_V(Srf);
  133.         }
  134.         }
  135.         break;
  136.     case CAGD_CONST_V_DIR:
  137.         if (Index + 1 > Srf -> VLength)
  138.         FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  139.  
  140.         Crv = BspCrvNew(CrvLen = Srf -> ULength,
  141.                 Srf -> UOrder, Srf -> PType);
  142.         GEN_COPY(Crv -> KnotVector, Srf -> UKnotVector,
  143.             sizeof(CagdRType) * (Srf -> ULength + Srf -> UOrder));
  144.  
  145.         for (i = IsNotRational; i <= MaxCoord; i++) {
  146.         CrvP = Crv -> Points[i];
  147.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_V(Srf);;
  148.         for (j = 0; j < CrvLen; j++) {
  149.             *CrvP++ = *SrfP;
  150.             SrfP += CAGD_NEXT_U(Srf);
  151.         }
  152.         }
  153.         break;
  154.     default:
  155.         FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
  156.         break;
  157.     }
  158.     return Crv;
  159. }
  160.  
  161.